<?php

namespace app\controller;

use support\Request;
use support\Response;
use app\model\Room;
use app\model\RoomUser;
use app\model\User;
use Carbon\Carbon;

class RoomController
{
    /**
     * 创建房间
     */
    public function create(Request $request): Response
    {
        $data = $request->post();
        $name = $data['name'] ?? '';
        $maxPlayers = $data['max_players'] ?? 4;
        $userId = $data['user_id'] ?? 0;

        if (!$userId) {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        // 检查用户是否存在
        $user = User::find($userId);
        if (!$user) {
            return json(['success' => false, 'message' => '用户不存在']);
        }

        // 如果用户没有填写房间名称，自动生成
        if (empty($name) || $name === '打牌记账房间') {
            $name = '打牌记账房间';
        }

        try {
            // 检查用户是否已经有活跃的房间
            $existingRoom = $this->getUserActiveRoom($userId);
            
            if ($existingRoom) {
                // 用户已有活跃房间，直接返回现有房间信息
                return json([
                    'success' => true,
                    'data' => [
                        'room' => [
                            'id' => $existingRoom->id,
                            'room_code' => $existingRoom->room_code,
                            'name' => $existingRoom->name,
                            'status' => $existingRoom->status,
                            'max_players' => $existingRoom->max_players,
                            'current_players' => $existingRoom->current_players,
                            'created_by' => $existingRoom->created_by,
                            'created_at' => $existingRoom->created_at->format('Y-m-d H:i:s')
                        ],
                        'is_existing_room' => true // 标记为现有房间
                    ]
                ]);
            }

            // 创建新房间
            $room = Room::createRoom([
                'name' => $name,
                'max_players' => $maxPlayers,
                'user_id' => $userId
            ]);

            // 创建者自动加入房间
            RoomUser::joinRoom($room->id, $userId);
            
            // 更新房间当前人数（确保正确）
            $room->refresh(); // 刷新房间模型
            $room->updateCurrentPlayers();
            
            // 发送WebSocket消息通知房间创建（包括创建者自己，确保能看到自己）
            // 注意：不依赖延迟发送，而是依赖以下机制：
            // 1. API响应中包含完整的用户列表（前端可立即显示）
            // 2. WebSocket连接建立时，handleUserConnect 会自动发送全量刷新（connect_success 消息包含 rooms_data）
            // 3. 如果 WebSocket 连接已建立，立即发送；否则等待连接建立后的全量刷新
            try {
                $websocketService = \app\service\WebSocketService::getInstance();
                
                // 尝试立即发送（如果 WebSocket 连接已建立并注册）
                // 如果失败，不影响，因为连接建立时会自动全量刷新
                $websocketService->sendUserJoinedMessage($room->id, $userId);
                error_log("已尝试发送房间创建WebSocket消息: room_id={$room->id}, user_id={$userId}");
                
            } catch (\Exception $wsException) {
                error_log('发送房间创建WebSocket消息失败（不影响，连接建立时会全量刷新）: ' . $wsException->getMessage());
                // WebSocket消息发送失败不影响主要功能，因为：
                // 1. API响应中已包含用户列表
                // 2. WebSocket连接建立时会自动发送全量刷新
            }
            
            // 获取完整的用户列表（包括创建者自己），确保前端能立即显示
            $roomUsers = RoomUser::where('room_id', $room->id)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->with('user')
                ->orderBy('joined_at', 'asc')
                ->get();
            
            $users = [];
            $owner = null;
            $otherUsers = [];
            
            foreach ($roomUsers as $ru) {
                if (!$ru->user) {
                    continue;
                }
                
                $userData = [
                    'id' => $ru->user->id,
                    'nickname' => $ru->user->nickname,
                    'avatar' => $ru->user->avatar,
                    'current_score' => $ru->current_score,
                    'joined_at' => $ru->joined_at ? $ru->joined_at->format('Y-m-d H:i:s') : '',
                    'is_owner' => $ru->user->id === $room->created_by
                ];
                
                if ($ru->user->id === $room->created_by) {
                    $owner = $userData;
                } else {
                    $otherUsers[] = $userData;
                }
            }
            
            if ($owner) {
                $users[] = $owner;
            }
            $users = array_merge($users, $otherUsers);
            
            return json([
                'success' => true,
                'data' => [
                    'room' => [
                        'id' => $room->id,
                        'room_code' => $room->room_code,
                        'name' => $room->name,
                        'status' => $room->status,
                        'max_players' => $room->max_players,
                        'current_players' => $room->current_players,
                        'created_by' => $room->created_by,
                        'created_at' => $room->created_at->format('Y-m-d H:i:s')
                    ],
                    'users' => $users, // 包含完整的用户列表，确保创建者能立即看到自己
                    'is_existing_room' => false // 标记为新房间
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '创建房间失败：' . $e->getMessage()]);
        }
    }

    /**
     * 获取用户的活跃房间
     */
    private function getUserActiveRoom($userId)
    {
        try {
            // 1. 首先查找用户创建的活跃房间（排除已结算的房间）
            $createdRoom = Room::where('created_by', $userId)
                ->whereIn('status', ['waiting', 'playing']) // 只包含等待中或进行中的房间，排除finished状态
                ->orderBy('created_at', 'desc')
                ->first();
            
            if ($createdRoom) {
                // 检查用户是否还在房间中
                $roomUser = \app\model\RoomUser::where('room_id', $createdRoom->id)
                    ->where('user_id', $userId)
                    ->where('status', \app\model\RoomUser::STATUS_ACTIVE)
                    ->first();
                
                if ($roomUser) {
                    return $createdRoom;
                }
            }
            
            // 2. 查找用户作为成员参与的活跃房间（包括已离开的，排除已结算的）
            $roomUser = \app\model\RoomUser::where('user_id', $userId)
                ->whereIn('status', [\app\model\RoomUser::STATUS_ACTIVE, \app\model\RoomUser::STATUS_LEFT])
                ->with('room')
                ->orderBy('joined_at', 'desc')
                ->first();
            
            if ($roomUser && $roomUser->room) {
                $room = $roomUser->room;
                // 检查房间是否仍然活跃（排除已结算的房间）
                if (in_array($room->status, ['waiting', 'playing'])) {
                    // 如果用户之前离开了，需要重新激活
                    if ($roomUser->status === \app\model\RoomUser::STATUS_LEFT) {
                        $this->reactivateUserInRoom($room->id, $userId);
                    }
                    return $room;
                }
                // 如果房间已结算，不返回房间，让用户创建新房间
                if ($room->status === 'finished') {
                    return null;
                }
            }
            
            return null;
        } catch (\Exception $e) {
            error_log('获取用户活跃房间失败: ' . $e->getMessage());
            return null;
        }
    }

    /**
     * 重新激活用户在房间中的状态
     */
    private function reactivateUserInRoom($roomId, $userId)
    {
        try {
            $roomUser = \app\model\RoomUser::where('room_id', $roomId)
                ->where('user_id', $userId)
                ->first();
            
            if ($roomUser) {
                $roomUser->status = \app\model\RoomUser::STATUS_ACTIVE;
                $roomUser->joined_at = Carbon::now();
                $roomUser->exited_at = null;
                $roomUser->save();
                
                // 更新房间当前人数
                $room = Room::find($roomId);
                if ($room) {
                    $room->updateCurrentPlayers();
                }
                
                // 发送用户重新加入的WebSocket消息
                try {
                    $websocketService = \app\service\WebSocketService::getInstance();
                    $websocketService->sendUserJoinedMessage($roomId, $userId);
                } catch (\Exception $wsException) {
                    error_log('发送用户重新加入WebSocket消息失败: ' . $wsException->getMessage());
                }
            }
        } catch (\Exception $e) {
            error_log('重新激活用户在房间中失败: ' . $e->getMessage());
        }
    }

    /**
     * 为新创建的房间生成二维码
     */
    private function generateQRCodeForNewRoom($roomCode): array
    {
        try {
      // 获取微信小程序配置
      $appId = config('wechat.mini_program.app_id', '');
      $appSecret = config('wechat.mini_program.secret', '');
      
      if (!empty($appId) && !empty($appSecret)) {
        // 获取access_token
        $accessToken = $this->getWxAccessToken($appId, $appSecret);
        if ($accessToken) {
          // 生成小程序码
          $wxQrcode = $this->generateWxQRCode($accessToken, $roomCode);
          if ($wxQrcode) {
            return [
              'type' => 'wx',
              'content' => 'data:image/png;base64,' . base64_encode($wxQrcode),
              'description' => '扫描二维码加入房间',
              'room_code' => $roomCode
            ];
          }
        }
      }
    } catch (\Exception $e) {
      // 微信接口失败时使用备用方案
    }
        
        // 使用备用方案生成二维码
        $fallbackQrcode = $this->generateFallbackQRCode($roomCode);
        return [
            'type' => 'fallback',
            'content' => $fallbackQrcode,
            'description' => '扫描二维码加入房间',
            'room_code' => $roomCode
        ];
    }
    
    /**
     * 根据房间代码获取房间信息
     */
    public function getByCode(Request $request): Response
    {
        $roomCode = $request->get('room_code');

        if (!$roomCode) {
            return json(['success' => false, 'message' => '房间代码不能为空']);
        }

        $room = Room::where('room_code', $roomCode)->first();
        if (!$room) {
            return json(['success' => false, 'message' => '房间不存在']);
        }

        // 已结算的房间可以查看，但不能加入
        // 这里不阻止查看已结算的房间信息

        // 刷新房间模型以确保获取最新数据
        $room->refresh();
        
        // 更新房间当前人数（确保准确）
        $room->updateCurrentPlayers();
        $room->refresh(); // 再次刷新以获取更新后的人数
        
        // 刷新所有 RoomUser 模型以确保获取最新分数
        $roomUsers = RoomUser::where('room_id', $room->id)
            ->where('status', RoomUser::STATUS_ACTIVE)
            ->get();
        foreach ($roomUsers as $roomUser) {
            $roomUser->refresh(); // 刷新每个用户的状态以获取最新分数
        }

        // 获取房间用户列表并统一排序
        $users = $this->getSortedRoomUsers($room);

        return json([
            'success' => true,
            'data' => [
                'id' => $room->id,
                'room_code' => $room->room_code,
                'name' => $room->name,
                'status' => $room->status,
                'max_players' => $room->max_players,
                'current_players' => $room->current_players,
                'created_by' => $room->created_by,
                'created_at' => $room->created_at->format('Y-m-d H:i:s'),
                'users' => $users
            ]
        ]);
    }

    /**
     * 加入房间
     */
    public function join(Request $request): Response
    {
        $data = $request->post();
        $roomCode = $data['room_code'] ?? '';
        $userId = $data['user_id'] ?? 0;

        if (!$roomCode || !$userId) {
            return json(['success' => false, 'message' => '参数不完整']);
        }

        // 检查用户是否存在
        $user = User::find($userId);
        if (!$user) {
            return json(['success' => false, 'message' => '用户不存在']);
        }

        // 查找房间
        $room = Room::where('room_code', $roomCode)->first();
        if (!$room) {
            return json(['success' => false, 'message' => '房间不存在']);
        }

        // 检查房间是否已满
        if ($room->current_players >= $room->max_players) {
            return json(['success' => false, 'message' => '房间已满']);
        }

        // 检查房间状态
        if ($room->status === 'finished') {
            return json(['success' => false, 'message' => '房间已结算，无法加入']);
        }
        
        if ($room->status !== 'waiting') {
            return json(['success' => false, 'message' => '房间状态不允许加入']);
        }

        try {
            // 检查用户是否已经在房间中
            $existingRoomUser = RoomUser::where('room_id', $room->id)
                ->where('user_id', $userId)
                ->first();
            
            $isRejoin = false;
            $roomUser = null;
            
            if ($existingRoomUser) {
                if ($existingRoomUser->status === RoomUser::STATUS_ACTIVE) {
                    // 用户已经在房间中，获取完整的用户列表
                    $room->refresh();
                    $roomUsers = RoomUser::where('room_id', $room->id)
                        ->where('status', RoomUser::STATUS_ACTIVE)
                        ->with('user')
                        ->orderBy('joined_at', 'asc')
                        ->get();
                    
                    $users = [];
                    $owner = null;
                    $otherUsers = [];
                    
                    foreach ($roomUsers as $ru) {
                        if (!$ru->user) {
                            continue;
                        }
                        
                        $userData = [
                            'id' => $ru->user->id,
                            'nickname' => $ru->user->nickname,
                            'avatar' => $ru->user->avatar,
                            'current_score' => $ru->current_score,
                            'joined_at' => $ru->joined_at ? $ru->joined_at->format('Y-m-d H:i:s') : '',
                            'is_owner' => $ru->user->id === $room->created_by
                        ];
                        
                        if ($ru->user->id === $room->created_by) {
                            $owner = $userData;
                        } else {
                            $otherUsers[] = $userData;
                        }
                    }
                    
                    if ($owner) {
                        $users[] = $owner;
                    }
                    $users = array_merge($users, $otherUsers);
                    
                    // 用户已经在房间中，直接返回
                    return json([
                        'success' => true,
                        'data' => [
                            'room' => [
                                'id' => $room->id,
                                'room_code' => $room->room_code,
                                'name' => $room->name,
                                'status' => $room->status,
                                'max_players' => $room->max_players,
                                'current_players' => $room->current_players,
                                'created_by' => $room->created_by
                            ],
                            'user' => [
                                'id' => $user->id,
                                'nickname' => $user->nickname,
                                'avatar' => $user->avatar,
                                'current_score' => $existingRoomUser->current_score
                            ],
                            'users' => $users, // 包含完整的用户列表
                            'already_joined' => true // 标记用户已在房间中
                        ]
                    ]);
                } elseif ($existingRoomUser->status === RoomUser::STATUS_LEFT) {
                    // 用户之前离开了，重新激活
                    $this->reactivateUserInRoom($room->id, $userId);
                    $isRejoin = true;
                    // 重新获取用户信息
                    $roomUser = RoomUser::where('room_id', $room->id)
                        ->where('user_id', $userId)
                        ->first();
                }
            } else {
                // 新用户加入房间
                $roomUser = RoomUser::joinRoom($room->id, $userId);
            }
            
            // 更新房间当前人数（在发送WebSocket消息之前）
            $room->refresh();
            $room->updateCurrentPlayers();
            $room->refresh(); // 刷新以确保获取最新人数

            // 确保所有 RoomUser 模型都被刷新，以确保获取最新分数
            $roomUsers = RoomUser::where('room_id', $room->id)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->get();
            foreach ($roomUsers as $ru) {
                $ru->refresh(); // 刷新每个用户的分数
            }

            // 发送WebSocket消息通知房间内其他用户
            // 注意：不依赖延迟发送，而是依赖以下机制：
            // 1. API响应中包含完整的用户列表（前端可立即显示）
            // 2. WebSocket连接建立时，handleUserConnect 会自动发送全量刷新（connect_success 消息包含 rooms_data）
            // 3. 如果 WebSocket 连接已建立，立即发送；否则等待连接建立后的全量刷新
            try {
                $websocketService = \app\service\WebSocketService::getInstance();
                
                // 尝试立即发送（如果 WebSocket 连接已建立并注册）
                // 如果失败，不影响，因为连接建立时会自动全量刷新
                if ($isRejoin) {
                    // 重新加入的消息
                    $websocketService->sendUserRejoinedMessage($room->id, $userId);
                } else {
                    // 新加入的消息
                    $websocketService->sendUserJoinedMessage($room->id, $userId);
                }
                error_log("已尝试发送用户加入/重新加入消息: room_id={$room->id}, user_id={$userId}, is_rejoin=" . ($isRejoin ? 'true' : 'false'));
                
            } catch (\Exception $wsException) {
                error_log('发送WebSocket消息失败（不影响，连接建立时会全量刷新）: ' . $wsException->getMessage());
                error_log('WebSocket异常堆栈: ' . $wsException->getTraceAsString());
                // WebSocket消息发送失败不影响主要功能，因为：
                // 1. API响应中已包含用户列表
                // 2. WebSocket连接建立时会自动发送全量刷新
            }

            // 确保 $roomUser 存在
            if (!$roomUser) {
                $roomUser = RoomUser::where('room_id', $room->id)
                    ->where('user_id', $userId)
                    ->first();
            }
            
            // 再次刷新房间信息，确保返回最新数据
            $room->refresh();
            $room->updateCurrentPlayers(); // 确保人数是最新的
            $room->refresh();
            
            // 获取完整的用户列表（排序后）- 与WebSocketService保持一致
            // 重新查询所有用户，确保获取最新分数
            $roomUsers = RoomUser::where('room_id', $room->id)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->with('user')
                ->orderBy('joined_at', 'asc')
                ->get();
            
            // 刷新每个用户的分数，确保返回最新值
            foreach ($roomUsers as $ru) {
                $ru->refresh(); // 刷新每个用户的分数
            }
            
            $users = [];
            $owner = null;
            $otherUsers = [];
            
            foreach ($roomUsers as $ru) {
                if (!$ru->user) {
                    continue; // 跳过无效的用户关系
                }
                
                $userData = [
                    'id' => $ru->user->id,
                    'nickname' => $ru->user->nickname,
                    'avatar' => $ru->user->avatar,
                    'current_score' => $ru->current_score,
                    'joined_at' => $ru->joined_at ? $ru->joined_at->format('Y-m-d H:i:s') : '',
                    'is_owner' => $ru->user->id === $room->created_by
                ];
                
                if ($ru->user->id === $room->created_by) {
                    $owner = $userData;
                } else {
                    $otherUsers[] = $userData;
                }
            }
            
            // 房主排在第一位，其他用户按加入时间排序（已在查询中排序）
            if ($owner) {
                $users[] = $owner;
            }
            $users = array_merge($users, $otherUsers);

            return json([
                'success' => true,
                'data' => [
                    'room' => [
                        'id' => $room->id,
                        'room_code' => $room->room_code,
                        'name' => $room->name,
                        'status' => $room->status,
                        'max_players' => $room->max_players,
                        'current_players' => $room->current_players,
                        'created_by' => $room->created_by
                    ],
                    'user' => [
                        'id' => $user->id,
                        'nickname' => $user->nickname,
                        'avatar' => $user->avatar,
                        'current_score' => $roomUser ? $roomUser->current_score : 0
                    ],
                    'users' => $users // 包含完整的排序用户列表，确保前端能立即显示
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '加入房间失败：' . $e->getMessage()]);
        }
    }

    /**
     * 获取房间列表
     */
    public function list(Request $request): Response
    {
        // 安全获取分页参数，确保是有效的整数
        $page = (int)$request->get('page', 1);
        $pageSize = (int)$request->get('page_size', 10);
        
        // 验证分页参数的有效性
        if ($page < 1) {
            $page = 1;
        }
        if ($pageSize < 1 || $pageSize > 100) {
            $pageSize = 10; // 默认值，最大100
        }
        
        $fromUserId = $request->get('from_user_id', ''); // 获取邀请者ID

        // 构建查询
        $query = Room::with(['creator', 'roomUsers' => function($query) {
            $query->where('status', RoomUser::STATUS_ACTIVE);
        }])
        ->where('status', '!=', 'finished'); // 排除已结算的房间
        
        // 如果有邀请者ID，只显示该用户创建的房间
        if (!empty($fromUserId)) {
            $query->where('created_by', $fromUserId);
        }
        
        // 执行查询
        $rooms = $query->orderBy('created_at', 'desc')
            ->paginate($pageSize, ['*'], 'page', $page);

        $roomList = $rooms->map(function ($room) {
            return [
                'id' => $room->id,
                'room_code' => $room->room_code,
                'name' => $room->name,
                'status' => $room->status,
                'max_players' => $room->max_players,
                'current_players' => $room->current_players,
                'creator' => [
                    'id' => $room->creator->id,
                    'nickname' => $room->creator->nickname,
                    'avatar' => $room->creator->avatar
                ],
                'created_at' => $room->created_at->format('Y-m-d H:i:s')
            ];
        });

        return json([
            'success' => true,
            'data' => [
                'rooms' => $roomList,
                'pagination' => [
                    'current_page' => $rooms->currentPage(),
                    'total_pages' => $rooms->lastPage(),
                    'total' => $rooms->total(),
                    'per_page' => $rooms->perPage()
                ]
            ]
        ]);
    }

    /**
     * 更新房间状态
     */
    public function updateStatus(Request $request): Response
    {
        $data = $request->post();
        $roomId = $data['room_id'] ?? 0;
        $status = $data['status'] ?? '';
        $userId = $data['user_id'] ?? 0;

        if (!$roomId || !$status || !$userId) {
            return json(['success' => false, 'message' => '参数不完整']);
        }

        $room = Room::find($roomId);
        if (!$room) {
            return json(['success' => false, 'message' => '房间不存在']);
        }

        // 检查权限（只有创建者可以更新状态）
        if ($room->created_by != $userId) {
            return json(['success' => false, 'message' => '无权限操作']);
        }

        try {
            $room->updateStatus($status);
            
            return json([
                'success' => true,
                'data' => [
                    'room' => [
                        'id' => $room->id,
                        'room_code' => $room->room_code,
                        'status' => $room->status
                    ]
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '更新房间状态失败：' . $e->getMessage()]);
        }
    }

    /**
     * 生成房间二维码
     */
    public function generateQRCode(Request $request): Response
    {
        $roomCode = $request->get('room_code');

        if (!$roomCode) {
            return json(['success' => false, 'message' => '房间代码不能为空']);
        }

        // 验证房间是否存在
        $room = Room::where('room_code', $roomCode)->first();
        if (!$room) {
            return json(['success' => false, 'message' => '房间不存在']);
        }

        try {
            // 获取微信小程序配置
            $appId = config('wechat.mini_program.app_id', '');
            $appSecret = config('wechat.mini_program.secret', '');
            
            if (empty($appId) || empty($appSecret)) {
                // 如果没有配置微信小程序参数，使用备用方案
                return $this->generateFallbackQRCode($roomCode);
            }

            // 获取access_token
            $accessToken = $this->getWxAccessToken($appId, $appSecret);
            if (!$accessToken) {
                return json(['success' => false, 'message' => '获取微信access_token失败']);
            }

            // 生成小程序码
            $qrCodeData = $this->generateWxQRCode($accessToken, $roomCode);
            if (!$qrCodeData) {
                return json(['success' => false, 'message' => '生成小程序码失败']);
            }

            // 将图片数据转换为base64
            $base64Image = base64_encode($qrCodeData);
            $imageUrl = 'data:image/png;base64,' . $base64Image;
            
            return json([
                'success' => true,
                'data' => [
                    'qrcode' => [
                        'url' => $imageUrl
                    ],
                    'room_code' => $roomCode,
                    'type' => 'miniprogram'
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '生成二维码失败：' . $e->getMessage()]);
        }
    }

    /**
     * 获取微信access_token
     */
    private function getWxAccessToken($appId, $appSecret)
    {
        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$appSecret}";
        
        $response = file_get_contents($url);
        $data = json_decode($response, true);
        
        if (isset($data['access_token'])) {
            return $data['access_token'];
        }
        
        return false;
    }

    /**
     * 生成微信小程序码
     */
    private function generateWxQRCode($accessToken, $roomCode = null, $customPath = null)
    {
        $url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={$accessToken}";
        
        // 构建路径
        if ($customPath) {
            $path = $customPath;
        } else if ($roomCode) {
            $path = "pages/splash/splash?roomCode={$roomCode}";
        } else {
            $path = "pages/splash/splash";
        }
        
        $postData = [
            'path' => $path,
            'width' => 300,
            'auto_color' => false,
            'line_color' => ['r' => 0, 'g' => 0, 'b' => 0],
            'is_hyaline' => false
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode === 200) {
            return $response;
        }
        
        return false;
    }

    // 保存二维码到本地的方法已被修改为直接返回base64数据
    
    /**
     * 生成用户专属二维码（可预生成）
     */
    public function generateUserQRCode(Request $request): Response
    {
        $userId = $request->get('user_id');
        $openId = $request->get('open_id', '');

        if (!$userId) {
            return json(['success' => false, 'message' => '用户ID不能为空']);
        }

        try {
            // 获取微信小程序配置
            $appId = config('wechat.mini_program.app_id', '');
            $appSecret = config('wechat.mini_program.secret', '');
            
            if (empty($appId) || empty($appSecret)) {
                // 如果没有配置微信小程序参数，使用备用方案
                return $this->generateUserFallbackQRCode($userId, $openId);
            }

            // 获取access_token
            $accessToken = $this->getWxAccessToken($appId, $appSecret);
            if (!$accessToken) {
                return json(['success' => false, 'message' => '获取微信access_token失败']);
            }

            // 生成固定的用户专属二维码，只包含用户标识信息
            // 这个二维码是固定的，扫码后会加载用户的房间列表
            $path = "pages/index/index?from_user_id={$userId}";
            if (!empty($openId)) {
                $path .= "&open_id={$openId}";
            }
            
            $qrCodeData = $this->generateWxQRCodeByPath($accessToken, $path);
            if (!$qrCodeData) {
                return json(['success' => false, 'message' => '生成小程序码失败']);
            }

            // 将图片数据转换为base64
            $base64Image = base64_encode($qrCodeData);
            $imageUrl = 'data:image/png;base64,' . $base64Image;
            
            return json([
                'success' => true,
                'data' => [
                    'qrcode' => [
                        'url' => $imageUrl
                    ],
                    'user_id' => $userId,
                    'type' => 'miniprogram',
                    'description' => '此二维码永久有效，好友扫码后可查看您的房间列表'
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '生成用户二维码失败：' . $e->getMessage()]);
        }
    }

    /**
     * 生成微信小程序码（根据路径）
     */
    private function generateWxQRCodeByPath($accessToken, $path)
    {
        $url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={$accessToken}";
        
        $postData = [
            'path' => $path,
            'width' => 300,
            'auto_color' => false,
            'line_color' => ['r' => 0, 'g' => 0, 'b' => 0],
            'is_hyaline' => false
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json'
        ]);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($httpCode === 200) {
            return $response;
        }
        
        return false;
    }

    /**
     * 用户专属二维码备用方案
     */
    private function generateUserFallbackQRCode($userId, $openId = '')
    {
        try {
            // 生成固定的用户专属链接，只包含用户标识信息
            $shareUrl = "pages/index/index?from_user_id={$userId}";
            if (!empty($openId)) {
                $shareUrl .= "&open_id={$openId}";
            }
            
            // 使用在线二维码生成服务并获取图片数据
            $qrCodeUrl = "https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=" . urlencode($shareUrl);
            $qrCodeData = file_get_contents($qrCodeUrl);
            
            if ($qrCodeData) {
                // 将图片数据转换为base64
                $base64Image = base64_encode($qrCodeData);
                $imageUrl = 'data:image/png;base64,' . $base64Image;
                
                return json([
                    'success' => true,
                    'data' => [
                        'qrcode' => [
                            'url' => $imageUrl
                        ],
                        'user_id' => $userId,
                        'type' => 'fallback',
                        'description' => '此二维码永久有效，好友扫码后可查看您的房间列表'
                    ]
                ]);
            }
            
            return json(['success' => false, 'message' => '生成备用二维码失败']);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '生成备用二维码异常：' . $e->getMessage()]);
        }
    }

    /**
     * 生成备用二维码
     */
    private function generateFallbackQRCode($roomCode = null, $customPath = null)
    {
        // 构建路径
        if ($customPath) {
            $path = $customPath;
        } else if ($roomCode) {
            $path = "pages/splash/splash?roomCode={$roomCode}";
        } else {
            $path = "pages/splash/splash";
        }
        
        // 使用第三方API生成二维码
        $qrcodeUrl = "https://api.qrserver.com/v1/create-qr-code/?size=300x300&data={$path}";
        
        // 获取二维码图片
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $qrcodeUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $imageData = curl_exec($ch);
        curl_close($ch);
        
        return [
            'type' => 'fallback',
            'content' => 'data:image/png;base64,' . base64_encode($imageData),
            'description' => '扫描二维码加入房间',
            'room_code' => $roomCode
        ];
    }
    
    /**
     * 验证用户房间状态
     */
    public function roomStatus(Request $request): Response
    {
        $userId = $request->post('user_id', 0);
        $roomId = $request->post('room_id', 0);
        
        if (!$userId || !$roomId) {
            return json(['success' => false, 'message' => '缺少必要参数']);
        }
        
        try {
            // 检查用户是否在指定房间中且状态为活跃
            $roomUser = RoomUser::where('user_id', $userId)
                ->where('room_id', $roomId)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->first();
            
            $inRoom = $roomUser !== null;
            $roomInfo = null;
            $userStatus = $inRoom ? 'active' : 'not_in_room';
            $message = $inRoom ? '用户在房间中' : '用户已退出房间';
            
            if ($inRoom) {
                // 如果在房间中，获取房间信息
                $room = Room::find($roomId);
                if ($room) {
                    $roomInfo = [
                        'id' => $room->id,
                        'room_code' => $room->room_code,
                        'name' => $room->name,
                        'status' => $room->status,
                        'user_status' => 'active'
                    ];
                }
            }
            
            // 即使不在房间中，也尝试获取房间基本信息（如果房间存在）
            if (!$inRoom) {
                $room = Room::find($roomId);
                if ($room) {
                    // 检查是否存在已离开的记录
                    $leftRecord = RoomUser::where('user_id', $userId)
                        ->where('room_id', $roomId)
                        ->where('status', RoomUser::STATUS_LEFT)
                        ->first();
                    
                    $userStatus = $leftRecord ? 'left' : 'not_in_room';
                    $message = $leftRecord ? '用户已离开该房间' : '用户未加入该房间';
                }
            }
            
            // 返回明确的状态信息
            return json([
                'success' => true,
                'message' => $message,
                'data' => [
                    'inRoom' => $inRoom,
                    'userStatus' => $userStatus,
                    'room' => $roomInfo,
                    'userId' => $userId,
                    'timestamp' => time() // 添加时间戳便于前端判断数据新鲜度
                ]
            ]);
        } catch (\Exception $e) {
            // 出错时默认返回不在房间中，确保前端行为安全
            return json([
                'success' => false,
                'message' => '验证房间状态失败：' . $e->getMessage(),
                'data' => [
                    'inRoom' => false, // 出错时默认返回不在房间中
                    'userStatus' => 'unknown',
                    'room' => null,
                    'userId' => $userId
                ]
            ]);
        }
    }
    
    /**
     * 用户退出房间
     */
    public function exit(Request $request): Response
    {
        $roomId = $request->post('room_id', 0);
        $userId = $request->post('user_id', 0);
        
        if (!$roomId || !$userId) {
            return json(['success' => false, 'message' => '参数不完整']);
        }
        
        // 检查房间是否存在
        $room = Room::find($roomId);
        if (!$room) {
            return json(['success' => false, 'message' => '房间不存在']);
        }
        
        // 检查用户是否在房间中
        $roomUser = RoomUser::where('room_id', $roomId)
            ->where('user_id', $userId)
            ->where('status', RoomUser::STATUS_ACTIVE)
            ->first();
        
        if (!$roomUser) {
            return json(['success' => true, 'message' => '用户已不在房间中']);
        }
        
        try {
            // 更新用户状态为已离开
            $roomUser->status = RoomUser::STATUS_LEFT;
            $roomUser->left_at = Carbon::now();
            $roomUser->save();
            
            // 更新房间当前人数
            $room->updateCurrentPlayers();
            
            // 如果房间没有活跃用户了，更新房间状态为已关闭
            $activeUsersCount = RoomUser::where('room_id', $roomId)
                ->where('status', RoomUser::STATUS_ACTIVE)
                ->count();
            
            if ($activeUsersCount === 0) {
                $room->status = 'closed';
                $room->closed_at = Carbon::now();
                $room->save();
            }
            
            return json([
                'success' => true,
                'data' => [
                    'message' => '退出房间成功',
                    'room_id' => $roomId,
                    'user_id' => $userId
                ]
            ]);
        } catch (\Exception $e) {
            return json(['success' => false, 'message' => '退出房间失败：' . $e->getMessage()]);
        }
    }
  
  /**
   * 生成统一的小程序码
   * 不包含房间信息的标准微信小程序码，用户扫码后进入banner页，
   * 在广告展示期间查询分享用户所在房间信息并自动加入
   */
  public function generateUniversalQRCode(Request $request): Response
  {
    // 使用固定路径，不包含房间参数
    $path = 'pages/splash/splash';
    
    try {
      // 获取微信小程序配置
      $appId = config('wechat.mini_program.app_id', '');
      $appSecret = config('wechat.mini_program.secret', '');
      
      if (empty($appId) || empty($appSecret)) {
        error_log('微信小程序配置不完整，无法生成标准小程序码');
        // 配置不完整时仍然返回备用方案
      } else {
        // 获取access_token
        $accessToken = $this->getWxAccessToken($appId, $appSecret);
        if (!$accessToken) {
          error_log('获取微信access_token失败');
        } else {
          // 使用微信官方的小程序码接口（wxacode）
          $miniCode = $this->generateWechatMiniCode($accessToken, $path);
          if ($miniCode) {
            return json([
              'success' => true,
              'data' => [
                'type' => 'miniprogram',
                'content' => [
                  'content' => 'data:image/png;base64,' . base64_encode($miniCode)
                ],
                'description' => '扫描小程序码',
                'app_id' => $appId
              ]
            ]);
          }
        }
      }
    } catch (\Exception $e) {
      error_log('生成小程序码异常: ' . $e->getMessage());
    }
    
    // 仅在微信接口完全不可用时才使用备用方案
    $fallbackResult = $this->generateFallbackQRCode('', $path);
    return json([
      'success' => true,
      'data' => [
        'type' => 'fallback',
        'content' => [
          'content' => $fallbackResult['content']
        ],
        'description' => '扫描小程序码',
        'room_code' => null  // 通用小程序码不包含特定房间代码
      ]
    ]);
  }
  
  /**
   * 生成微信标准小程序码
   * 使用最新的wxacode接口
   */
  private function generateWechatMiniCode($accessToken, $path)
  {
    // 使用微信获取小程序码的接口（wxacode）
    $url = "https://api.weixin.qq.com/wxa/getwxacode?access_token={$accessToken}";
    
    $postData = [
      'path' => $path,
      'width' => 430, // 小程序码推荐宽度
      'auto_color' => false,
      'line_color' => ['r' => 0, 'g' => 0, 'b' => 0],
      'is_hyaline' => false
    ];
    
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
      'Content-Type: application/json'
    ]);
    
    $response = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
    curl_close($ch);
    
    // 检查是否返回了图片数据
    if ($httpCode === 200 && strpos($contentType, 'image/') === 0) {
      return $response;
    }
    
    // 如果返回的是错误信息，记录下来
    if (strpos($contentType, 'application/json') === 0) {
      $errorInfo = json_decode($response, true);
      error_log('微信小程序码生成失败: ' . json_encode($errorInfo));
    }
    
    return false;
  }
  
  /**
   * Helper method to generate wx QR code with config handling
   */
  private function generateWxQRCodeWithConfig($roomCode = null, $customPath = null) {
    // 获取配置
    $config = config('wechat.mini_program', []);
    
    // 检查配置是否完整
    if (!isset($config['app_id']) || !isset($config['secret'])) {
      throw new \Exception('微信小程序配置不完整');
    }
    
    // 获取access_token
    $accessToken = $this->getWxAccessToken($config['app_id'], $config['secret']);
    if (!$accessToken) {
      return false;
    }
    
  // 使用现有的generateWxQRCode方法
  return $this->generateWxQRCode($accessToken, $roomCode, $customPath);
  }

  /**
   * 获取房间用户列表并统一排序
   * 确保所有客户端看到的用户顺序一致
   */
  private function getSortedRoomUsers($room)
  {
    // 获取所有活跃用户
    $roomUsers = $room->roomUsers()
        ->where('status', RoomUser::STATUS_ACTIVE)
        ->with('user')
        ->get();

    // 分离房主和其他用户
    $owner = null;
    $otherUsers = [];

    foreach ($roomUsers as $roomUser) {
        $userData = [
            'id' => $roomUser->user->id,
            'nickname' => $roomUser->user->nickname,
            'avatar' => $roomUser->user->avatar,
            'current_score' => $roomUser->current_score,
            'joined_at' => $roomUser->joined_at->format('Y-m-d H:i:s'),
            'is_owner' => $roomUser->user->id === $room->created_by,
            'room_user_id' => $roomUser->id, // 添加room_user_id用于排序
            'joined_at_timestamp' => $roomUser->joined_at->timestamp // 添加时间戳用于排序
        ];

        if ($roomUser->user->id === $room->created_by) {
            $owner = $userData;
        } else {
            $otherUsers[] = $userData;
        }
    }

    // 其他用户按加入时间排序（joined_at字段）
    usort($otherUsers, function($a, $b) {
        // 首先按加入时间排序
        $timeCompare = $a['joined_at_timestamp'] - $b['joined_at_timestamp'];
        if ($timeCompare !== 0) {
            return $timeCompare;
        }
        // 如果时间相同，按用户ID排序确保稳定性
        return $a['id'] - $b['id'];
    });

    // 构建最终排序结果：房主在第一位，其他用户按加入顺序排列
    $sortedUsers = [];
    if ($owner) {
        $sortedUsers[] = $owner;
    }
    $sortedUsers = array_merge($sortedUsers, $otherUsers);

    // 移除临时字段
    foreach ($sortedUsers as &$user) {
        unset($user['room_user_id']);
        unset($user['joined_at_timestamp']);
    }

    return $sortedUsers;
  }

  /**
   * 设置茶饭规则
   */
  public function setTeaMeal(Request $request): Response
  {
      $data = $request->post();
      $roomId = $data['room_id'] ?? 0;
      $userId = $data['user_id'] ?? 0;
      $teaMealLimit = $data['tea_meal_limit'] ?? 0;
      $teaMealPercentage = $data['tea_meal_percentage'] ?? 0;
      $teaMealMode = $data['tea_meal_mode'] ?? 'percentage';
      $teaMealFixedAmount = $data['tea_meal_fixed_amount'] ?? 0;

      if (!$roomId || !$userId) {
          return json(['success' => false, 'message' => '参数不完整']);
      }

      if ($teaMealLimit <= 0) {
          return json(['success' => false, 'message' => '茶饭上限必须大于0']);
      }

      // 验证模式参数
      if (!in_array($teaMealMode, ['percentage', 'fixed'])) {
          return json(['success' => false, 'message' => '茶饭费模式无效']);
      }

      if ($teaMealMode === 'percentage' && ($teaMealPercentage < 0 || $teaMealPercentage > 100)) {
          return json(['success' => false, 'message' => '扣除比例必须在0-100之间']);
      }

      if ($teaMealMode === 'fixed' && $teaMealFixedAmount <= 0) {
          return json(['success' => false, 'message' => '固定茶饭费必须大于0']);
      }

      try {
          // 验证房间是否存在
          $room = Room::find($roomId);
          if (!$room) {
              return json(['success' => false, 'message' => '房间不存在']);
          }

          // 验证用户是否为房主
          $roomUser = RoomUser::where('room_id', $roomId)
              ->where('user_id', $userId)
              ->where('is_owner', 1)
              ->first();

          if (!$roomUser) {
              return json(['success' => false, 'message' => '只有房主可以设置茶饭规则']);
          }

          // 更新房间的茶饭设置
          $room->tea_meal_limit = $teaMealLimit;
          $room->tea_meal_percentage = $teaMealPercentage;
          $room->tea_meal_mode = $teaMealMode;
          $room->tea_meal_fixed_amount = $teaMealFixedAmount;
          $room->save();

          // 发送WebSocket消息通知房间内其他用户
          try {
              $websocketService = \app\service\WebSocketService::getInstance();
              $websocketService->sendTeaMealSettingsMessage(
                  $roomId,
                  $userId,
                  $teaMealLimit,
                  $teaMealPercentage,
                  $teaMealMode,
                  $teaMealFixedAmount
              );
          } catch (\Exception $e) {
              error_log('发送茶饭设置WebSocket消息失败: ' . $e->getMessage());
          }

          return json([
              'success' => true,
              'message' => '茶饭设置已保存',
              'data' => [
                  'tea_meal_limit' => $teaMealLimit,
                  'tea_meal_percentage' => $teaMealPercentage,
                  'tea_meal_mode' => $teaMealMode,
                  'tea_meal_fixed_amount' => $teaMealFixedAmount
              ]
          ]);

      } catch (\Exception $e) {
          error_log('设置茶饭规则失败: ' . $e->getMessage());
          return json(['success' => false, 'message' => '设置茶饭规则失败']);
      }
  }

  /**
   * 获取房间茶饭费统计
   */
  public function getTeaMealStats(Request $request): Response
  {
      $roomId = $request->get('room_id');

      if (!$roomId) {
          return json(['success' => false, 'message' => '房间ID不能为空']);
      }

      try {
          $teaMealService = \app\service\TeaMealService::class;
          $stats = $teaMealService::getRoomTeaMealStats($roomId);

          if (!$stats) {
              return json(['success' => false, 'message' => '获取茶饭费统计失败']);
          }

          return json([
              'success' => true,
              'data' => $stats
          ]);

      } catch (\Exception $e) {
          error_log('获取茶饭费统计失败: ' . $e->getMessage());
          return json(['success' => false, 'message' => '获取茶饭费统计失败']);
      }
  }

}
